﻿using System;
using System.Collections;
using System.Collections.Generic;
using Framework;
using TrueSync;
using TrueSync.Physics2D;

public enum TargetRectEnum
{
    BodyPositionRect,
    BodyHitRectUp,
    BodyHitRectMid,
    BodyHitRectDown,
    DynamicBodyHitRect,
    GuardAlarmRect,
}

public enum RectOperationTypeEnum
{
    ModifySize,
    RestoreSize,
    
    ChangeToFlySubitemNoCollision,
    RestoreStatus,

    New,
    Delete,
}

public class RectOperationEventEffector : BaseEventEffector
{
    public TargetRectEnum Target;
    public RectOperationTypeEnum RectOperationType;
    #region 占位框
    public TSVector2 BodyPositionLeftUp, BodyPositionDownRight;
    #endregion

    #region 体位框
    public TSVector2 BodyHitLeftUp, BodyHitRightDown;
    #endregion

    #region 攻击体位框
    public TSVector2 DynamicBodyHitLeftUp, DynamicBodyHitRightDown;
    public string DynamicBodyHitHangpointName;
    public AttachToParentSyncMethodEnum DynamicBodyHitRectSyncMethod;
    public bool IsSetToFlySubitemNoCollision;
    #endregion

    #region 防御警示框
    public TSVector2 GuardAlarmHitLeftUp, GuardAlarmRightDown;
    public string GuardAlarmHitHangpointName;
    public AttachToParentSyncMethodEnum GuardAlarmRectSyncMethod;
    #endregion

    public override void DoEvent(ObjHandle<LogicEntity> owner, params object[] allParams)
    {
        LogicPhysicsComponent physicsComponent = owner.handle.GetLogicComponent<LogicPhysicsComponent>();

        if (Target == TargetRectEnum.BodyPositionRect)
        {
            if(RectOperationType == RectOperationTypeEnum.ModifySize)
            {
                physicsComponent.BodyPositionRect.Shape = new RectangleShape(BodyPositionLeftUp, BodyPositionDownRight);
            }
            else if(RectOperationType == RectOperationTypeEnum.Delete)
            {
                physicsComponent.BodyPositionRect.Enabled = false;
            }
            else if(RectOperationType == RectOperationTypeEnum.RestoreSize)
            {
                physicsComponent.BodyPositionRect.Shape = new RectangleShape(physicsComponent.BodyPositionRectLeftup, physicsComponent.BodyPositionRectRightdown);
                physicsComponent.BodyPositionRect.Enabled = true;
            }
        }
        else if (Target == TargetRectEnum.BodyHitRectUp || Target == TargetRectEnum.BodyHitRectMid || Target == TargetRectEnum.BodyHitRectDown)
        {
            Fixture bodyHitRect = null;
            if (Target == TargetRectEnum.BodyHitRectUp)
                bodyHitRect = physicsComponent.BodyHitRectUp;
            else if (Target == TargetRectEnum.BodyHitRectMid)
                bodyHitRect = physicsComponent.BodyHitRectMid;
            else
                bodyHitRect = physicsComponent.BodyHitRectDown;

            if(RectOperationType == RectOperationTypeEnum.ModifySize)
            {
                bodyHitRect.Shape = new RectangleShape(BodyHitLeftUp, BodyHitRightDown);
            }
            else if(RectOperationType == RectOperationTypeEnum.RestoreSize)
            {
                bodyHitRect.Enabled = true;
                if(Target == TargetRectEnum.BodyHitRectUp)
                {
                    bodyHitRect.Shape = new RectangleShape(physicsComponent.BodyHitUpRectLeftup, physicsComponent.BodyHitUpRectRightdown);
                }
                else if(Target == TargetRectEnum.BodyHitRectMid)
                {
                    bodyHitRect.Shape = new RectangleShape(physicsComponent.BodyHitMidRectLeftup, physicsComponent.BodyHitMidRectRightdown);
                }
                else
                {
                    bodyHitRect.Shape = new RectangleShape(physicsComponent.BodyHitDownRectLeftup, physicsComponent.BodyHitDownRectRightdown);
                }
            }
            else if(RectOperationType == RectOperationTypeEnum.ChangeToFlySubitemNoCollision)
            {
                bodyHitRect.CollisionCategories = Category.BodyHitNoCollideWithFlySubitem;
            }
            else if(RectOperationType == RectOperationTypeEnum.RestoreStatus)
            {
                bodyHitRect.CollisionCategories = Category.BodyHit;
            }
            else if(RectOperationType == RectOperationTypeEnum.Delete)
            {
                bodyHitRect.Enabled = false;
            }
        }
        else if(Target == TargetRectEnum.DynamicBodyHitRect)
        {
            if(RectOperationType == RectOperationTypeEnum.New)
            {
                BodyHitRect dynamicBodyHitRect = new BodyHitRect(new RectangleShape(DynamicBodyHitLeftUp, DynamicBodyHitRightDown), TSVector2.zero, 0, owner);
                dynamicBodyHitRect.BodyHitRectType = BodyHitRectTypeEnum.Dynamic;
                dynamicBodyHitRect.CollisionCategories = IsSetToFlySubitemNoCollision? Category.BodyHitNoCollideWithFlySubitem : Category.BodyHit;
                LogicAnimationComponent animationComponent = owner.handle.GetLogicComponent<LogicAnimationComponent>();
                animationComponent.AddToHangpoint(DynamicBodyHitHangpointName, dynamicBodyHitRect, DynamicBodyHitRectSyncMethod);
                physicsComponent.DynamicsBodyHitRects.Add(dynamicBodyHitRect);
                FightGame.Instance.CollisionWorld.AddFixture(dynamicBodyHitRect);
            }
            else if(RectOperationType == RectOperationTypeEnum.Delete)
            {
                LogicAnimationComponent animationComponent = owner.handle.GetLogicComponent<LogicAnimationComponent>();
                for (int i = 0; i < physicsComponent.DynamicsBodyHitRects.Count; i++)
                {
                    animationComponent.RemoveFromHangpoint(physicsComponent.DynamicsBodyHitRects[i]);
                    physicsComponent.DynamicsBodyHitRects[i].OnDestroy();
                }

                physicsComponent.DynamicsBodyHitRects.Clear();
            }
        }
        else if(Target == TargetRectEnum.GuardAlarmRect)
        {
            if (RectOperationType == RectOperationTypeEnum.New)
            {
                GuardAlarmRect guardHitRect = new GuardAlarmRect(new RectangleShape(GuardAlarmHitLeftUp, GuardAlarmRightDown), TSVector2.zero, 0, owner);
                LogicAnimationComponent animationComponent = owner.handle.GetLogicComponent<LogicAnimationComponent>();
                animationComponent.AddToHangpoint(GuardAlarmHitHangpointName, guardHitRect, GuardAlarmRectSyncMethod);
                physicsComponent.GuardAlarmRects.Add(guardHitRect);
                FightGame.Instance.CollisionWorld.AddFixture(guardHitRect);
            }
            else if (RectOperationType == RectOperationTypeEnum.Delete)
            {
                LogicAnimationComponent animationComponent = owner.handle.GetLogicComponent<LogicAnimationComponent>();
                for (int i = 0; i < physicsComponent.GuardAlarmRects.Count; i++)
                {
                    animationComponent.RemoveFromHangpoint(physicsComponent.GuardAlarmRects[i]);
                    physicsComponent.GuardAlarmRects[i].OnDestroy();
                }

                physicsComponent.GuardAlarmRects.Clear();
            }
        }
    }

    public override void OnDestroy()
    {
    }

    public override void Serialize(EByte ms)
    {
        ms.WriteInt((int)Target);
        ms.WriteInt((int)RectOperationType);
        switch(Target)
        {
            case TargetRectEnum.BodyPositionRect:
                if(RectOperationType == RectOperationTypeEnum.ModifySize)
                {
                    ms.WriteLong(BodyPositionLeftUp.x.RawValue); ms.WriteLong(BodyPositionLeftUp.y.RawValue);
                    ms.WriteLong(BodyPositionDownRight.x.RawValue); ms.WriteLong(BodyPositionDownRight.y.RawValue);
                }
                break;
            case TargetRectEnum.BodyHitRectUp:
            case TargetRectEnum.BodyHitRectMid:
            case TargetRectEnum.BodyHitRectDown:
                if(RectOperationType == RectOperationTypeEnum.ModifySize)
                {
                    ms.WriteLong(BodyHitLeftUp.x.RawValue); ms.WriteLong(BodyHitLeftUp.y.RawValue);
                    ms.WriteLong(BodyHitRightDown.x.RawValue); ms.WriteLong(BodyHitRightDown.y.RawValue);
                }
                break;
            case TargetRectEnum.DynamicBodyHitRect:
                if (RectOperationType == RectOperationTypeEnum.New)
                {
                    ms.WriteString(DynamicBodyHitHangpointName);
                    ms.WriteInt((int)DynamicBodyHitRectSyncMethod);
                    ms.WriteLong(DynamicBodyHitLeftUp.x.RawValue); ms.WriteLong(DynamicBodyHitLeftUp.y.RawValue);
                    ms.WriteLong(DynamicBodyHitRightDown.x.RawValue); ms.WriteLong(DynamicBodyHitRightDown.y.RawValue);
                    ms.WriteInt(IsSetToFlySubitemNoCollision ? 1 : 0);
                }
                break;
            case TargetRectEnum.GuardAlarmRect:
                if(RectOperationType == RectOperationTypeEnum.New)
                {
                    ms.WriteString(GuardAlarmHitHangpointName);
                    ms.WriteInt((int)GuardAlarmRectSyncMethod);
                    ms.WriteLong(GuardAlarmHitLeftUp.x.RawValue); ms.WriteLong(GuardAlarmHitLeftUp.y.RawValue);
                    ms.WriteLong(GuardAlarmRightDown.x.RawValue); ms.WriteLong(GuardAlarmRightDown.y.RawValue);
                }
                break;
        }
    }

    public override void Deserialize(EByte ms)
    {
        Target = (TargetRectEnum)ms.ReadInt();
        RectOperationType = (RectOperationTypeEnum)ms.ReadInt();
        switch(Target)
        {
            case TargetRectEnum.BodyPositionRect:
                if (RectOperationType == RectOperationTypeEnum.ModifySize)
                {
                    BodyPositionLeftUp = new TSVector2(FP.FromRaw(ms.ReadLong()), FP.FromRaw(ms.ReadLong()));
                    BodyPositionDownRight = new TSVector2(FP.FromRaw(ms.ReadLong()), FP.FromRaw(ms.ReadLong()));
                }
                break;
            case TargetRectEnum.BodyHitRectUp:
            case TargetRectEnum.BodyHitRectMid:
            case TargetRectEnum.BodyHitRectDown:
                if (RectOperationType == RectOperationTypeEnum.ModifySize)
                {
                    BodyHitLeftUp = new TSVector2(FP.FromRaw(ms.ReadLong()), FP.FromRaw(ms.ReadLong()));
                    BodyHitRightDown = new TSVector2(FP.FromRaw(ms.ReadLong()), FP.FromRaw(ms.ReadLong()));
                }
                break;
            case TargetRectEnum.DynamicBodyHitRect:
                if (RectOperationType == RectOperationTypeEnum.New)
                {
                    DynamicBodyHitHangpointName = ms.ReadString();
                    DynamicBodyHitRectSyncMethod = (AttachToParentSyncMethodEnum)ms.ReadInt();
                    DynamicBodyHitLeftUp = new TSVector2(FP.FromRaw(ms.ReadLong()), FP.FromRaw(ms.ReadLong()));
                    DynamicBodyHitRightDown = new TSVector2(FP.FromRaw(ms.ReadLong()), FP.FromRaw(ms.ReadLong()));
                    IsSetToFlySubitemNoCollision = ms.ReadInt() == 1;
                }
                break;
            case TargetRectEnum.GuardAlarmRect:
                if (RectOperationType == RectOperationTypeEnum.New)
                {
                    GuardAlarmHitHangpointName = ms.ReadString();
                    GuardAlarmRectSyncMethod = (AttachToParentSyncMethodEnum)ms.ReadInt();
                    GuardAlarmHitLeftUp = new TSVector2(FP.FromRaw(ms.ReadLong()), FP.FromRaw(ms.ReadLong()));
                    GuardAlarmRightDown = new TSVector2(FP.FromRaw(ms.ReadLong()), FP.FromRaw(ms.ReadLong()));
                }
                break;
        }
    }

}
